<###################################################################################################################################
 # OS_Tools.ps1 #>Set-StrictMode -Version Latest;<##################################################################################################################################>
function Add-LocalGroup {[CmdletBinding()] Param (
    [Parameter (Mandatory= $False)][string]$ComputerName= $ENV:ComputerName,
    [Parameter (Mandatory= $True )][string]$GroupName,
    [Parameter (Mandatory= $True )][string]$GroupDescription
);    Write-Verbose "Creating $ComputerName\$GroupName";    $cn= [ADSI]"WinNT://$ComputerName";
    $gp= $cn.Create('Group',"$GroupName"); $gp.SetInfo();
    $gp.Description= $GroupDescription; $gp.SetInfo();}
<##################################################################################################################################>
function Add-LocalGroupMember {<#
.SYNOPSIS
	what is it?

.DESCRIPTION
	what does it do?

.PARAMETER ParameterName
	what can you tell it?

.EXAMPLE
	how do you make it go?	

	Description
	-----------
	what happens when you do this?

.INPUTS
	System.String.

.OUTPUTS
	None.

.NOTES
	Additional information about the function or script.
##>
[CmdletBinding()] Param (
    [Parameter (Mandatory= $False)][string]$ComputerName= $ENV:ComputerName,
    [Parameter (Mandatory= $True )][string]$GroupName,
    [Parameter (Mandatory= $False)][string]$UserDomain= $ENV:UserDomain,
    [Parameter (Mandatory= $False)][string]$UserName= $ENV:UserName
);

    Write-Verbose "Adding $UserDomain\$UserName to $ComputerName\$GroupName";
    ([ADSI]"WinNT://$ComputerName/$GroupName,Group").psbase.Invoke('Add',([ADSI]"WinNT://$UserDomain/$UserName").path);
};<##################################################################################################################################>
function Reset-Service {<#
.SYNOPSIS
	what is it?

.DESCRIPTION
	what does it do?

.PARAMETER ParameterName
	what can you tell it?

.EXAMPLE
	how do you make it go?	

	Description
	-----------
	what happens when you do this?

.INPUTS
	System.String.

.OUTPUTS
	None.

.NOTES
##>
[CmdletBinding()] Param (
    [Parameter (Mandatory= $True)][string]$Name,
    [Parameter (Mandatory= $False, ValueFromPipeline= $True)][string[]]$ComputerName= '127.0.0.1'
    );

BEGIN {};

PROCESS { $ComputerName |% {
    Write-Verbose $_;
    Invoke-Command -Verbose -ComputerName $_ -ArgumentList $Name -ScriptBlock {
        Param ($Name);
        $DependentServices= @();
        Get-Service -Name $Name -DependentServices | Where-Object {$_.Status -eq "Running"} | ForEach-Object {$DependentServices+= $_.Name};
        Restart-Service -Force $Name;
        ForEach ($Name in $DependentServices) {Start-Service -Verbose $Name};
    };
}};

END {};
};
<##################################################################################################################################>
function Get-ComputerConfiguration {[CmdletBinding()] Param (
    [parameter (Mandatory= $False, ValueFromPipeline= $True)]
    [string[]]
    $ComputerName= $env:COMPUTERNAME
    );

BEGIN {};

PROCESS { $ComputerName | % {
    Write-Verbose $_;
    $Win32_ComputerSystem=$Win32_Processor= $Null;

    try {$Win32_ComputerSystem= Get-WmiObject Win32_ComputerSystem -ComputerName $_ -Property Manufacturer,Model,NumberOfProcessors,NumberOfLogicalProcessors,TotalPhysicalMemory -ErrorAction Stop;}
    catch {Write-Warning $_; return};
    try {$Win32_Processor= Get-WmiObject Win32_Processor -ComputerName $_ -Property NumberOfCores -ErrorAction Stop;}
    catch {Write-Warning $_; return};

    $NumberOfCores= 0; $Win32_Processor.NumberOfCores | % {$NumberOfCores+= $_};
	@{
		ComputerName		= $_;
		Manufacturer		= $Win32_ComputerSystem.Manufacturer;
		Model				= $Win32_ComputerSystem.Model;
		NumberOfSockets		= [int]$Win32_ComputerSystem.NumberOfProcessors;
		NumberOfCores		= [int](& {if ($NumberOfCores -eq 0) {$Win32_ComputerSystem.NumberOfProcessors} else {$NumberOfCores}});
		NumberOfLogicalCores= [int](& {if ($Win32_ComputerSystem.NumberOfLogicalProcessors -eq $null) {$Win32_ComputerSystem.NumberOfProcessors} else {$Win32_ComputerSystem.NumberOfLogicalProcessors}});
		TotalPhysicalMemory	= [int][math]::Round($Win32_ComputerSystem.TotalPhysicalMemory/1048576.0);
		IsClustered			= [bool](& {if ((Get-WmiObject -Class Win32_SystemServices -ComputerName $_ | Select-Object PartComponent | Where-Object {$_ -like '*ClusSvc*'}) -eq $null) {$false} else {$true}});
	};
}};

END {};
};

<##################################################################################################################################>
Write-Verbose "OS_Tools Loaded";